package com.auxgroup.hr.front.service.process.impl;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.math.BigDecimal;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ExecutorService;

import javax.annotation.Resource;

import com.auxgroup.hr.front.commons.utils.*;
import com.auxgroup.hr.front.dao.domain.*;
import com.auxgroup.hr.front.dao.repository.PsCModAttTRepository;
import com.auxgroup.hr.front.service.hireperson.impl.HireEducatServiceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Example;
import org.springframework.stereotype.Service;

import com.auxgroup.hr.front.commons.BaseRetCode;
import com.auxgroup.hr.front.commons.config.BusinessConfig;
import com.auxgroup.hr.front.commons.enums.StepStatusEnum;
import com.auxgroup.hr.front.commons.exception.FrontException;
import com.auxgroup.hr.front.commons.vo.UserDTO;
import com.auxgroup.hr.front.commons.vo.WfFileRespVo;
import com.auxgroup.hr.front.dao.repository.PsCAppUserInstRepository;
import com.auxgroup.hr.front.dao.repository.PsCWfFileAttRepository;
import com.auxgroup.hr.front.dozer.IObjectMapper;
import com.auxgroup.hr.front.service.process.WfFileService;
import com.auxgroup.hr.front.service.thread.DownWfFileThread;

/** 
 * @author lvliuhao 
 * @version 创建时间：2018年7月17日 下午8:38:23 
 * 流程文件服务类 
 */
@Service("wfFileService")
public class WfFileServiceImpl implements WfFileService {
	
	private static final Logger logger = LoggerFactory.getLogger(HireEducatServiceImpl.class);
	
	@Value("${auxgroup.hr.ftp.filepath}")
	private  String FTP_BASEPATH;//图片路径
	
	@Resource(name = "dozerMapper")
	protected IObjectMapper objectMapper;
	
	@Autowired
	private PsCAppUserInstRepository psCAppUserInstRepository;
	
	@Autowired
	private PsCModAttTRepository psCModAttTRepository;
	
	@Autowired
	private FtpFileUtil ftpUtil;
	
	@Autowired
	private BusinessConfig businessConfig;
	
	@Override
	public PsCModAttT getFileAttInfo(PsCModAttTPrimary primary) {
		return psCModAttTRepository.findOne(primary);
	}
	
	@Override
	public PsCModAttT getFileAttInfos(String transNum, BigDecimal seqNbr) {
		PsCModAttT query = new PsCModAttT();
		query.setcTransactionNbr(transNum);
		query.setSeqnbr(seqNbr);
		List<PsCModAttT> atts = psCModAttTRepository.findAll(Example.of(query));
		if(atts==null || atts.isEmpty()){
			return null;
		}
		return atts.get(0);
	}

	@Override
	public PsCModAttT uploadWfFile(String base64, UserDTO user, PsCModAttTPrimary primary, String wfType, String originName) {
		PsCModAttT wfFile = objectMapper.map(primary, PsCModAttT.class);
		try {
			BigDecimal maxSeqnbr = psCModAttTRepository.getMaxSeqNbr(primary.getcTransactionNbr(), primary.getcStepNbr(), primary.getcUserNbr());
			if(maxSeqnbr==null){
				maxSeqnbr = new BigDecimal(1);
			}else{
				maxSeqnbr = maxSeqnbr.add(new BigDecimal(1));
			}
			String suffix = File2Byte.getImgSuffixFromBase64(base64);
			StringBuilder ftpFileName = new StringBuilder(primary.getcTransactionNbr());
			ftpFileName.append("-");
			ftpFileName.append(primary.getcStepNbr());
			ftpFileName.append("-");
			ftpFileName.append(primary.getcUserNbr());
			ftpFileName.append("-");
			ftpFileName.append(maxSeqnbr);
			ftpFileName.append(".");
			ftpFileName.append(suffix);
			//上传附件
			String ftpPath = getFtpPath();
			byte[] imgByte = File2Byte.base64ToImgByte(base64, businessConfig.getEmplePhotoResourceLocation());
			Boolean isSucc = ftpUtil.uploadFile(ftpPath,ftpFileName.toString(), new ByteArrayInputStream(imgByte));
			if(!isSucc){
				throw new FrontException(BaseRetCode.CODE_ERROR_HIREFILE_UPLOAD_FAILED);
			}
//			wfFile.setHrsRowAddOprid(user.getOprId());
//			wfFile.setHrsRowAddDttm(new Timestamp(System.currentTimeMillis()));
//			wfFile.setHrsRowUpdOprid(user.getOprId());
//			wfFile.setHrsRowUpdDttm(new Timestamp(System.currentTimeMillis()));
			wfFile.setLastupdoprid(user.getOprId());
			wfFile.setLastupddttm(new Timestamp(System.currentTimeMillis()));
			wfFile.setOprid(user.getOprId());
			wfFile.setSeqnbr(maxSeqnbr);
			wfFile.setAttachsysfilename(ftpFileName.toString());
			if(originName.length() > 64) {
				//截取文件名
				originName = originName.substring(originName.length() - 64, originName.length());
			}
			wfFile.setAttachuserfile(originName);
			wfFile.setFilePath(ftpPath);

			//FIXME 文件序号？？
			ObjectFieldUtils.handleNullValue(wfFile);
			wfFile = psCModAttTRepository.save(wfFile);
		} catch (Exception e) {
			logger.error("wf file upload failed：",e);
			throw new FrontException(BaseRetCode.CODE_ERROR_HIREFILE_UPLOAD_FAILED);
			
		}
		return wfFile;
	}
	
	
	/**
	 * 获取ftp文件路径
	 * @return
	 */
	public String getFtpPath(){
		StringBuilder filePath = new StringBuilder(FTP_BASEPATH);
		filePath.append(DateUtils.format(new Date(), DateUtils.FORMAT_YYYY));
		filePath.append("/WFL/");
		return filePath.toString();
	}

	@Override
	public List<WfFileRespVo> getWfFiles(String cTransactionNbr,UserDTO user,String wfType) {
		List<WfFileRespVo> wfFileRespVos = new ArrayList<WfFileRespVo>();
		//不需要根据当前审批人来获取附件
//		PsCAppUserInst userInst = getUserInst(cTransactionNbr,user);
//		if(userInst==null){
//			return wfFileRespVos;
//		}
		PsCModAttT queryFile = new PsCModAttT();
		queryFile.setcTransactionNbr(cTransactionNbr);
//		queryFile.setcStepNbr(userInst.getcStepNbr());
//		queryFile.setcUserNbr(userInst.getcUserNbr());
		List<PsCModAttT> wfFiles = psCModAttTRepository.findAll(Example.of(queryFile));
		if(wfFiles!=null&&!wfFiles.isEmpty()){
			Integer corePoolSize=wfFiles.size()>3?3:wfFiles.size();
			Integer maxPoolSize = wfFiles.size()>3?wfFiles.size():wfFiles.size()+1;
			ExecutorService executor = ThreadPoolUtil.getExecutor(corePoolSize,maxPoolSize, 30, "wfFileDownLoad");
			DownWfFileThread downloadThread = null; 
			for (PsCModAttT wfFile : wfFiles) {
				downloadThread = new DownWfFileThread(ftpUtil, getFtpPath(), wfFile, wfFileRespVos, businessConfig);
				executor.execute(downloadThread);
			}
			executor.shutdown();//线程池执行完毕时，关闭线程池
			//等线程池执行完毕
			if(isExecutorOver(executor)){
				return wfFileRespVos;
			}
		}
		return wfFileRespVos;
	}
	
	/**
	 * 递归调用看线程是否执行完毕
	 * @param executor
	 * @return
	 */
	private Boolean isExecutorOver(ExecutorService executor){
		//如果线程池执行完毕就返回true
		if(executor.isTerminated()){
			logger.info("wf file loading success");
			return true;
		}else{
			//没有执行完毕的时候，3秒钟之后再次检查
			logger.info("wf file loading...");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
			}
			return isExecutorOver(executor);
		}
	}
	
	
	/**
	 * 获取当前待审批用户的步骤信息
	 * @param transNum
	 * @param user
	 * @return
	 */
	private PsCAppUserInst getUserInst(String transNum,UserDTO user){
		PsCAppUserInst userInst = new PsCAppUserInst();
		userInst.setcTransactionNbr(transNum);
		userInst.setcStepStatus(StepStatusEnum.STEP_STATUS_P.getStatus());
		//获取待审批的流程用户
		List<PsCAppUserInst> userInsts = psCAppUserInstRepository.findAll(Example.of(userInst));
		if(userInsts==null||userInsts.isEmpty()){
			return null;
		}
		//判断当前用户是否为待审批的流程用户
		for (PsCAppUserInst inst : userInsts) {
			if(user.getOprId().equals(inst.getOprid())){
				return inst;
			}
		}
		return null;
	}


	@Override
	public void delWfFiles(String cTransactionNbr, Boolean isdelFile) {
		PsCModAttT query = new PsCModAttT();
		query.setcTransactionNbr(cTransactionNbr);
		List<PsCModAttT> wfFiles = psCModAttTRepository.findAll(Example.of(query));
		if(isdelFile){
			if(wfFiles!=null&&!wfFiles.isEmpty()){
				String[] fileNames = new String[wfFiles.size()];
				String filePath = wfFiles.get(0).getFilePath();
				for (int i = 0; i < wfFiles.size(); i++) {
					fileNames[i]= wfFiles.get(i).getAttachsysfilename();
				}
				ftpUtil.deleteFile(filePath, fileNames);
			}
		}
		psCModAttTRepository.deleteInBatch(wfFiles);
	}


	@Override
	public void delWfFile(String cTransactionNbr, String seqnbr) {
		PsCModAttTPrimary primary = new PsCModAttTPrimary();
		primary.setcStepNbr(new BigDecimal(0));
		primary.setcUserNbr(new BigDecimal(0));
		primary.setcTransactionNbr(cTransactionNbr);
		primary.setSeqnbr(new BigDecimal(seqnbr));
		PsCModAttT file = psCModAttTRepository.findOne(primary);
		if(file!=null){
			String localFilePath = businessConfig.getFtpFileResourceLocation()+"/"+file.getAttachsysfilename();
			File localFile = new File(localFilePath);
			if(localFile.exists()&&localFile.isFile()){
				localFile.delete();
			}
			ftpUtil.deleteFile(file.getFilePath(), file.getAttachsysfilename());
			psCModAttTRepository.delete(file);
		}
	}
}
 